import * as xhook from 'xhook'
import { enableXhook } from './xhookjs'
import { sendMessage, setNamespace } from 'webext-bridge/window'
import { yapiImportCheck } from './yapiImport'

// 保存原生的 console 方法，避免被页面劫持
const nativeConsole = {
    log: console.log.bind(console),
    groupCollapsed: console.groupCollapsed.bind(console),
    groupEnd: console.groupEnd.bind(console),
}

declare global {
    // 给window添加xhook
    interface Window {
        xhook: typeof xhook
        xhookEnabled?: boolean
    }
}

const genResponse = (data: string): xhook.Response => {
    return {
        data: data,
        text: data,
        status: 200,
        statusText: '',
        headers: {},
        xml: null as any, // xhook 类型定义问题，这里需要兼容处理
    }
}

const MOCK_RESPONSE_ENABLED_STATUS_KEY = '__MOCK_RESPONSE_ENABLED_STATUS__'

export default defineUnlistedScript({
    // world: 'MAIN', // 在主世界运行，可以直接访问页面环境
    main() {
        // 通信命名空间
        setNamespace('overrideFetch')

        // yapi检测
        yapiImportCheck()

        // 启用拦截

        // 检测是否开启拦截
        // 1: loading 2: notEnabled 3: enabled
        const mockResponseEnabledStatus = localStorage.getItem(
            MOCK_RESPONSE_ENABLED_STATUS_KEY,
        )

        sendMessage('getConfig', undefined).then((res) => {
            const newStatus = res?.enabled ? '3' : '2'
            localStorage.setItem(MOCK_RESPONSE_ENABLED_STATUS_KEY, newStatus)
            if (newStatus !== mockResponseEnabledStatus) {
                location.reload()
            }
        })

        if (mockResponseEnabledStatus !== '3') {
            return
        }

        enableXhook()
        if (!window.xhook) {
            nativeConsole.log(
                '%cMockResponse插件加载失败',
                'color: red; font-weight: bold;',
            )
            return
        }

        nativeConsole.log(
            '%cMockResponse插件加载成功',
            'color: green; font-weight: bold;',
        )

        window.xhook.before(function (request, callback) {
            // console.log('before', request)
            // 将 headers 转换为普通对象，避免 DataCloneError
            const headersObj: Record<string, any> = {}
            if (request.headers) {
                for (const key in request.headers) {
                    headersObj[key] = request.headers[key]
                }
            }
            
            sendMessage('beforeRequest', {
                url: request.url,
                method: request.method,
                headers: headersObj,
                body: request.body,
            }).then((res) => {
                if (res && res?.resBody) {
                    nativeConsole.groupCollapsed(
                        `%cMock: %c${res?.matchedUrl || request.url}`,
                        'color: green; font-weight: bold;',
                        '',
                    )
                    nativeConsole.log('Request:', {
                        url: request.url,
                        method: request.method,
                        headers: headersObj,
                        body: request.body,
                    })
                    nativeConsole.log('ResBody:', JSON.parse(res?.resBody))
                    nativeConsole.groupEnd()
                    callback(genResponse(res?.resBody))
                    return
                }
                callback()
            })
        })
        window.xhook.after(function (request, response) {
            // console.log('after', request, response)
            // response.data ='{\"code\":500,\"msg\":\"用户名或密码错误456\",\"data\":null}'
            // response.text = response.data
            // console.log('response',request.id, response)
        })
    },
})
